﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Payton.WP7.Common.Model;
using Payton.WP7.Common.Sina;
using Hammock;
using Hammock.Authentication.OAuth;
using System.Text.RegularExpressions;
using Payton.WP7.Common;
using System.Diagnostics;
using Payton.WP7.ViewModel;
using Payton.WP7.Common.Interface;
using Microsoft.Practices.Prism.Events;
using Payton.WP7.Common.Event;
using Microsoft.Phone.Shell;
using System.IO.IsolatedStorage;
using System.Windows.Media.Imaging;
using Microsoft.Phone.Tasks;
using System.Windows.Controls.Primitives;
using ShakeGestures;

namespace Payton.WP7.Views
{
    public partial class MainView : PhoneApplicationPage
    {
        private ProgressIndicator _progressIndicator;
        private bool hasInit = false;
        MainViewModel _mainViewModel;
        private IEventAggregator _ev;
        PhotoChooserTask pct;

        ScrollViewer svHome;
        ScrollViewer svMentions;
        ScrollViewer svCommentsToMe;
        ScrollViewer svCommentsByMe;
        //ScrollViewer svSearch;

        public MainView()
        {
            if (PhoneApplicationController.Current.AppSetting.EnableShakeToRefresh)
            {
                ShakeGesturesHelper.Instance.ShakeGesture += Instance_ShakeGesture;
                ShakeGesturesHelper.Instance.MinimumRequiredMovesForShake = 4;
                ShakeGesturesHelper.Instance.Active = true;
            }

            InitializeComponent();

            MainViewModel mainViewModel = new MainViewModel();
            _mainViewModel = mainViewModel;

            this.DataContext = _mainViewModel;

            if (_mainViewModel.HasBindedAccount)
            {
                pct = new PhotoChooserTask();
                pct.Completed += new EventHandler<PhotoResult>(pct_Completed);
            }
            else
            {
                HideMenu();
            }

            _mainViewModel.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(_mainViewModel_PropertyChanged);

            Loaded += (s, e) =>
            {
                if (hasInit)
                    return;
                hasInit = true;
                if (PhoneApplicationService.Current.State.ContainsKey("PivotSelectedIndex"))
                    _mainViewModel.PivotSelectedIndex = (int)PhoneApplicationService.Current.State["PivotSelectedIndex"];

                _ev = PhoneApplicationController.Current.Container.Resolve<IEventAggregator>();

                _ev.GetEvent<NavigationRequestEvent>().Subscribe(HandlleNavigateRequest);


                _mainViewModel.OnNextPagePerformed += (i, p) =>
                {
                    switch (p)
                    {
                        case "home":
                            if (svHome == null && _mainViewModel.Items.Count > 0)
                            {

                                svHome = ContentGrid.GetChild<ScrollViewer>();
                                svHome.ManipulationCompleted += (sender, eventArgs) =>
                                {
                                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                                    {
                                        if (eventArgs.TotalManipulation.Translation.Y < -100 && svHome.VerticalOffset >= svHome.ScrollableHeight)
                                        {
                                            _mainViewModel.NextPage("home");
                                            Debug.WriteLine("retrieve next page of home");
                                        }
                                        else if (eventArgs.TotalManipulation.Translation.Y > 100 && svHome.VerticalOffset <= 0)
                                        {
                                            _mainViewModel.RefreshTimeLine("home");
                                            Debug.WriteLine("refresh home");
                                        }
                                    });


                                };
                                SetAppIconButton(0);
                            }

                            break;
                        case "mentions":
                            if (svMentions == null && _mainViewModel.Mentions.Count > 0)
                            {
                                svMentions = mentionList.GetChild<ScrollViewer>();
                                svMentions.ManipulationCompleted += (sender, eventArgs) =>
                                {
                                    if (eventArgs.TotalManipulation.Translation.Y < -100 && svMentions.VerticalOffset >= svMentions.ScrollableHeight)
                                    {
                                        _mainViewModel.NextPage("mentions");
                                        Debug.WriteLine("retrieve next page of home");
                                    }
                                    else if (eventArgs.TotalManipulation.Translation.Y > 100 && svMentions.VerticalOffset <= 0)
                                    {
                                        _mainViewModel.RefreshTimeLine("mentions");
                                        Debug.WriteLine("refresh home");
                                    }
                                };
                            }
                            break;
                        case "commenttome":
                            if (svCommentsToMe == null && _mainViewModel.CommentsToMe.Count > 0)
                            {
                                svCommentsToMe = commentsToMeList.GetChild<ScrollViewer>();
                                svCommentsToMe.ManipulationCompleted += (sender, eventArgs) =>
                                {
                                    if (eventArgs.TotalManipulation.Translation.Y < -100 && svCommentsToMe.VerticalOffset >= svCommentsToMe.ScrollableHeight)
                                    {
                                        _mainViewModel.NextPage("commenttome");
                                        Debug.WriteLine("retrieve next page of commenttome");
                                    }
                                    else if (eventArgs.TotalManipulation.Translation.Y > 100 && svCommentsToMe.VerticalOffset <= 0)
                                    {
                                        _mainViewModel.RefreshTimeLine("commenttome");
                                        Debug.WriteLine("refresh commenttome");
                                    }
                                };
                            }
                            break;
                        case "commentbyme":
                            if (svCommentsByMe == null && _mainViewModel.CommentsByMe.Count > 0)
                            {
                                svCommentsByMe = commentsByMeList.GetChild<ScrollViewer>();
                                svCommentsByMe.ManipulationCompleted += (sender, eventArgs) =>
                                {
                                    if (eventArgs.TotalManipulation.Translation.Y < -100 && svCommentsByMe.VerticalOffset >= svCommentsByMe.ScrollableHeight)
                                    {
                                        _mainViewModel.NextPage("commentbyme");
                                        Debug.WriteLine("retrieve next page of commentbyme");
                                    }
                                    else if (eventArgs.TotalManipulation.Translation.Y > 100 && svCommentsByMe.VerticalOffset <= 0)
                                    {
                                        _mainViewModel.RefreshTimeLine("commentbyme");
                                        Debug.WriteLine("refresh commentbyme");
                                    }
                                };
                            }
                            break;
                        case "search":

                            break;
                        default:
                            break;
                    }
                };
            };
        }

        // Set the data context of the TextBlock to the answer.
        void Instance_ShakeGesture(object sender, ShakeGestureEventArgs e)
        {
            switch (_mainViewModel.PivotSelectedIndex)
            {
                case 0:
                    _mainViewModel.RefreshTimeLine("home");
                    break;
                case 1: _mainViewModel.RefreshTimeLine("mentions");
                    break;
                case 2: _mainViewModel.RefreshTimeLine("commenttome");
                    break;
                case 3: _mainViewModel.RefreshTimeLine("commentbyme");
                    break;
                default:
                    break;
            }
        }

        void _mainViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            Debug.WriteLine("Property changed:" + e.PropertyName);
            switch (e.PropertyName)
            {
                case "HasBindedAccount":
                    if (!_mainViewModel.HasBindedAccount)
                    {
                        HideMenu();
                    }
                    else
                    {
                        PopulateMenu();
                    }
                    break;
                case "Loading":
                    if (_mainViewModel.Loading)
                    {
                        progressIndicator.IsIndeterminate = true;
                        HideMenu();
                    }
                    else if (_mainViewModel.HasBindedAccount)
                    {
                        progressIndicator.IsIndeterminate = false;
                        PopulateMenu();
                    }
                    break;
                case "PivotSelectedIndex":
                    if (PhoneApplicationService.Current.State.ContainsKey("PivotSelectedIndex"))
                        PhoneApplicationService.Current.State["PivotSelectedIndex"] = _mainViewModel.PivotSelectedIndex;
                    else
                        PhoneApplicationService.Current.State.Add("PivotSelectedIndex", _mainViewModel.PivotSelectedIndex);
                    SetAppIconButton(_mainViewModel.PivotSelectedIndex);
                    break;
                default:
                    break;
            }
        }

        void pct_Completed(object sender, PhotoResult e)
        {
            if (Microsoft.Phone.Net.NetworkInformation.NetworkInterface.NetworkInterfaceType == Microsoft.Phone.Net.NetworkInformation.NetworkInterfaceType.Ethernet)
            {
                MessageBox.Show(AppResx.WarnDisconnectPcWhenChoosingPicture, AppResx.WarnText, MessageBoxButton.OK);
                return;
            }
            if (e.Error == null && e.TaskResult == TaskResult.OK)
            {
                BitmapImage bmi = new BitmapImage();
                _mainViewModel.ImageToSend = bmi;
                bmi.SetSource(e.ChosenPhoto);
            }
        }

        void Current_Deactivated(object sender, DeactivatedEventArgs e)
        {

        }

        //protected override void OnHold(System.Windows.Input.GestureEventArgs e)
        //{
        //    base.OnHold(e);
        //    if (!_mainViewModel.ShowQuickSetting)
        //    {
        //        _mainViewModel.ShowQuickSetting = true;
        //    }
        //    else
        //    {
        //        _mainViewModel.ShowQuickSetting = false;
        //    }
        //}

        void aboutItem_Click(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri("/Views/AboutPanorama.xaml", UriKind.RelativeOrAbsolute));
            //throw new NotImplementedException();
        }

        void settingItem_Click(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri("/Views/SettingView.xaml", UriKind.RelativeOrAbsolute));
            //throw new NotImplementedException();
        }

        private void PopulateMenu()
        {
            var mi1 = null as ApplicationBarMenuItem;
            var mi2 = null as ApplicationBarMenuItem;
            var mi3 = null as ApplicationBarMenuItem;

            mi1 = new ApplicationBarMenuItem
            {
                Text = AppResx.AccountManagementText,
            };
            mi1.Click += account_management_Click;

            mi2 = new ApplicationBarMenuItem
            {
                Text = AppResx.UserSettingText,
            };
            mi2.Click += settingItem_Click;

            mi3 = new ApplicationBarMenuItem
            {
                Text = AppResx.AboutUsText,
            };
            mi3.Click += aboutItem_Click;

            this.ApplicationBar.MenuItems.Clear();
            this.ApplicationBar.MenuItems.Add(mi1);
            this.ApplicationBar.MenuItems.Add(mi2);
            this.ApplicationBar.MenuItems.Add(mi3);

            if (!this.ApplicationBar.IsVisible
                && (this.ApplicationBar.Buttons.Count > 0 || this.ApplicationBar.MenuItems.Count > 0))
                this.ApplicationBar.IsVisible = true;
        }

        private void HideMenu()
        {
            if (this.ApplicationBar == null)
                return;
            if (this.ApplicationBar.IsVisible)
                this.ApplicationBar.IsVisible = false;
        }

        private void SetAppIconButton(int pIndex)
        {
            ApplicationBar.Buttons.Clear();

            switch (pIndex)
            {
                case 0:
                    ApplicationBarIconButton send = new ApplicationBarIconButton(new Uri("/Images/AppBarIcons/edit.png", UriKind.Relative)) { Text = AppResx.NewStatusText };
                    send.Click += new EventHandler(send_Click);
                    ApplicationBarIconButton refreash_home = new ApplicationBarIconButton(new Uri("/Images/AppBarIcons/refresh.png", UriKind.Relative)) { Text = AppResx.RefreshText };
                    refreash_home.Click += new EventHandler(refreash_home_Click);

                    ApplicationBarIconButton search = new ApplicationBarIconButton(new Uri("/Images/AppBarIcons/appbar.search.rest.png", UriKind.Relative)) { Text = AppResx.SearchTopicText };
                    search.Click += new EventHandler(search_Click);
                    ApplicationBar.Buttons.Add(send);
                    ApplicationBar.Buttons.Add(search);
                    ApplicationBar.Buttons.Add(refreash_home);

                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        ContentGrid.Focus();
                    });

                    break;
                case 1:
                    send = new ApplicationBarIconButton(new Uri("/Images/AppBarIcons/edit.png", UriKind.Relative)) { Text = AppResx.NewStatusText };
                    send.Click += new EventHandler(send_Click);
                    ApplicationBarIconButton refreash_mentions = new ApplicationBarIconButton(new Uri("/Images/AppBarIcons/refresh.png", UriKind.Relative)) { Text = AppResx.RefreshText };
                    refreash_mentions.Click += new EventHandler(refreash_mentions_Click);

                    ApplicationBar.Buttons.Add(send);
                    ApplicationBar.Buttons.Add(refreash_mentions);

                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        mentionList.Focus();
                    });
                    break;
                case 2:
                    send = new ApplicationBarIconButton(new Uri("/Images/AppBarIcons/edit.png", UriKind.Relative)) { Text = AppResx.NewStatusText };
                    send.Click += new EventHandler(send_Click);
                    ApplicationBarIconButton refreash_comment_to_me = new ApplicationBarIconButton(new Uri("/Images/AppBarIcons/refresh.png", UriKind.Relative)) { Text = AppResx.RefreshText };
                    refreash_comment_to_me.Click += new EventHandler(refreash_comment_to_me_Click);



                    ApplicationBar.Buttons.Add(send);
                    ApplicationBar.Buttons.Add(refreash_comment_to_me);

                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        commentsToMeList.Focus();
                    });

                    break;
                case 3:
                    send = new ApplicationBarIconButton(new Uri("/Images/AppBarIcons/edit.png", UriKind.Relative)) { Text = AppResx.NewStatusText };
                    send.Click += new EventHandler(send_Click);
                    ApplicationBarIconButton refreash_comment_by_me = new ApplicationBarIconButton(new Uri("/Images/AppBarIcons/refresh.png", UriKind.Relative)) { Text = AppResx.RefreshText };
                    refreash_comment_by_me.Click += new EventHandler(refreash_comment_by_me_Click);


                    ApplicationBar.Buttons.Add(send);
                    ApplicationBar.Buttons.Add(refreash_comment_by_me);

                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        commentsByMeList.Focus();
                    });
                    break;
                case 4:
                    var performSearch = new ApplicationBarIconButton(new Uri("/Images/AppBarIcons/appbar.search.rest.png", UriKind.Relative)) { Text = AppResx.SearchTopicText };
                    performSearch.Click += new EventHandler(performSearch_Click);
                    var clearSearchText = new ApplicationBarIconButton(new Uri("/Images/AppBarIcons/delete.png", UriKind.Relative)) { Text = AppResx.EmptyText };
                    clearSearchText.Click += new EventHandler(clearSearchText_Click);

                    ApplicationBar.Buttons.Add(performSearch);
                    ApplicationBar.Buttons.Add(clearSearchText);

                    break;
                case 5:
                    send = new ApplicationBarIconButton(new Uri("/Images/AppBarIcons/appbar.send.update.png", UriKind.Relative)) { Text = AppResx.SendText };
                    send.Click += new EventHandler(sendStatus_Click);
                    ApplicationBarIconButton add_image = new ApplicationBarIconButton(new Uri("/Images/AppBarIcons/camera.png", UriKind.Relative)) { Text = AppResx.ChoosePixText };
                    add_image.Click += new EventHandler(add_image_Click);

                    ApplicationBarIconButton delete_image = new ApplicationBarIconButton(new Uri("/Images/AppBarIcons/delete.png", UriKind.Relative)) { Text = AppResx.RemovePixText };
                    delete_image.Click += new EventHandler(delete_image_Click);
                    ApplicationBar.Buttons.Add(send);
                    ApplicationBar.Buttons.Add(add_image);
                    ApplicationBar.Buttons.Add(delete_image);

                    break;
                default:
                    break;
            }

            //throw new NotImplementedException();
        }




        void clearSearchText_Click(object sender, EventArgs e)
        {
            _mainViewModel.ClearSearch.Execute();
            //throw new NotImplementedException();
        }

        void performSearch_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(tbSearchWord.Text))
            {
                return;
            }
            _mainViewModel.SearchKeyword = tbSearchWord.Text;
            _mainViewModel.Search.Execute();

            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                searchList.Focus();
            });

            //throw new NotImplementedException();
        }

        void delete_image_Click(object sender, EventArgs e)
        {
            _mainViewModel.ClearPhoto.Execute();
            //throw new NotImplementedException();
        }

        void add_image_Click(object sender, EventArgs e)
        {
            ChoosePhotoMethod();
            //_mainViewModel.ChoosePhoto.Execute();
            //throw new NotImplementedException();
        }

        void refreash_comment_to_me_Click(object sender, EventArgs e)
        {
            _mainViewModel.RefreshTimeLine("commenttome");
            _mainViewModel.OnRefreshed += (item, type) =>
            {
                if (item != null && type == "commenttome")
                    this.commentsToMeList.ScrollIntoView(item);
                _mainViewModel.OnRefreshed = null;
            };
        }

        void refreash_comment_by_me_Click(object sender, EventArgs e)
        {
            _mainViewModel.RefreshTimeLine("commentbyme");
            _mainViewModel.OnRefreshed += (item, type) =>
            {
                if (item != null && type == "commentbyme")
                    this.commentsByMeList.ScrollIntoView(item);
                _mainViewModel.OnRefreshed = null;
            };
        }

        void refreash_mentions_Click(object sender, EventArgs e)
        {
            _mainViewModel.RefreshTimeLine("mentions");
            _mainViewModel.OnRefreshed += (item, type) =>
            {
                if (item != null && type == "mentions")
                    this.commentsToMeList.ScrollIntoView(item);
                _mainViewModel.OnRefreshed = null;
            };
        }

        void search_Click(object sender, EventArgs e)
        {
            _mainViewModel.PivotSelectedIndex = 4;
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                tbSearchWord.Focus();
            });
        }

        void refreash_home_Click(object sender, EventArgs e)
        {
            _mainViewModel.RefreshTimeLine("home");
            _mainViewModel.OnRefreshed += (item, type) =>
            {
                if (item != null && type == "home")
                    this.ContentGrid.ScrollIntoView(item);
                _mainViewModel.OnRefreshed = null;
            };
        }

        void send_Click(object sender, EventArgs e)
        {
            _mainViewModel.PivotSelectedIndex = 5;


            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                tbSend.Focus();
            });
            //throw new NotImplementedException();

        }

        void sendStatus_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(tbSend.Text))
            {
                return;
            }
            _mainViewModel.StatusToUpdate = tbSend.Text;
            _mainViewModel.Send.Execute();

        }

        public void HandlleNavigateRequest(Common.Event.NavigationContext context)
        {
            var accountID = context.SimpleParameter.ToString();
            if (string.IsNullOrEmpty(accountID) || context.Destination == null)
            {
                return;
            }

            Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    NavigationService.Navigate(new Uri("/Views/AuthPage.xaml?accountid=" + accountID, UriKind.RelativeOrAbsolute));
                }
            );
        }

        private void CommentList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count > 0)
            {
                var status = (e.AddedItems[0] as SNSStatusViewModel).Item;
                var key = status.RetweetedStatus.Id.ToString();

                if (PhoneApplicationService.Current.State.ContainsKey(key))
                {
                    PhoneApplicationService.Current.State.Remove(key);
                }

                PhoneApplicationService.Current.State.Add(key, status.RetweetedStatus);

                NavigationService.Navigate(new Uri("/Views/StatusDetailView.xaml?" + key, UriKind.RelativeOrAbsolute));
            }
            var list = sender as ListBox;
            if (list != null)
            {
                list.SelectionChanged -= CommentList_SelectionChanged;
                list.SelectedIndex = -1;
                list.SelectionChanged += CommentList_SelectionChanged;
            }

        }

        private void ContentGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count > 0)
            {
                var status = (e.AddedItems[0] as SNSStatusViewModel).Item;
                var key = status.Id.ToString();

                if (PhoneApplicationService.Current.State.ContainsKey(key))
                {
                    PhoneApplicationService.Current.State.Remove(key);
                }

                PhoneApplicationService.Current.State.Add(key, status);
                NavigationService.Navigate(new Uri("/Views/StatusDetailView.xaml?" + key, UriKind.RelativeOrAbsolute));
            }
            var list = sender as ListBox;
            if (list != null)
            {
                list.SelectionChanged -= ContentGrid_SelectionChanged;
                list.SelectedIndex = -1;
                list.SelectionChanged += ContentGrid_SelectionChanged;
            }

        }

        private void ChoosePhotoMethod()
        {
            var ir = _mainViewModel.AppSetting.UploadImageResolution;
            pct.ShowCamera = true;
            pct.PixelHeight = ir.Height;
            pct.PixelWidth = ir.Width;

            pct.Show();
        }

        protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
        {
            base.OnBackKeyPress(e);

            var result = MessageBox.Show(AppResx.ConfirmExitText, AppResx.ConfirmExitTitleText, MessageBoxButton.OKCancel);

            if (result != MessageBoxResult.OK)
            {
                e.Cancel = true;
            }
        }

        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {
            //base.OnNavigatedFrom(e);
            //ContentGrid.ItemsSource = null;
            if (PhoneApplicationController.Current.AppSetting.EnableShakeToRefresh)
            {
                ShakeGesturesHelper.Instance.ShakeGesture -= Instance_ShakeGesture;
                ShakeGesturesHelper.Instance.MinimumRequiredMovesForShake = 4;
                ShakeGesturesHelper.Instance.Active = false;
            }
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            //base.OnNavigatedTo(e);
            //ContentGrid.ItemsSource = _mainViewModel.Items;
            var count = NavigationService.BackStack.Count();
            for (int i = 0; i <
                count; i++)
            {
                if (NavigationService.CanGoBack)
                    NavigationService.RemoveBackEntry();
            }

            if (PhoneApplicationController.Current.AppSetting.EnableShakeToRefresh)
            {
                ShakeGesturesHelper.Instance.ShakeGesture += Instance_ShakeGesture;
                ShakeGesturesHelper.Instance.MinimumRequiredMovesForShake = 4;
                ShakeGesturesHelper.Instance.Active = true;
            }
        }

        private void account_management_Click(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri("/Views/AccountManagmentView.xaml", UriKind.Relative));
        }

        private void User_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {

            var statusVM = sender as SNSStatusViewModel;
            if (statusVM == null)
                return;

            var user = statusVM.Item.User;
            var key = user.AccountName + "=" + user.AccountID;

            if (PhoneApplicationService.Current.State.ContainsKey(key))
            {
                PhoneApplicationService.Current.State.Remove(key);
            }

            PhoneApplicationService.Current.State.Add(key, user);
            NavigationService.Navigate(new Uri("/Views/UserHomeView.xaml?" + key, UriKind.Relative));
        }
    }
}
